package com.itlong.cloud.intercept;


import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.GZIPUtils;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@Order(0)
public class CreateBaiduFaceParamIntercept {
    private static Logger LOG = LoggerFactory.getLogger(CreateBaiduFaceParamIntercept.class);

    //拦截点
    @Pointcut("execution(* com.itlong.cloud.controller..*.*(..)) && @annotation(com.itlong.cloud.annotation.UnCreateBaiduFace)")
    public void executeService(){}

    @Value("${" + PlatformConstants.PROPERTY_OPERATE_MINI_CONTENT_AES_ENCRYPT_KEY + "}")
    String propertyOperateMiniContentAesEncryptKey;

    @Value("${" + PlatformConstants.PROPERTY_OPERATE_MD5_ENCRYPT_KEY + "}")
    String propertyOperateMd5EncryptKey;

    /**
     * <desc>
     *      请求入参和返回拦截器方法
     * </desc>
     *
     * @author chengshican
     * @createDate 2020/09/14
     */
    //@Around("executeService()")
    public Object handleParam(ProceedingJoinPoint thisJoinPoint) throws Throwable{
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestUrl = request.getRequestURL().toString();
        //入参密文
        //String encryptScript = request.getParameter("encryptScript");
       // System.out.println("adad******************"+encryptScript);
        String script = request.getParameter("encryptScript");
        System.out.println("ttttttttttttttttttttttttt******************"+script);
        String encryptScript= GZIPUtils.uncompress(script);
        System.out.println("adad******************"+encryptScript);
        if (StringUtils.isBlank(encryptScript)) {
            //加密串未携带，参数异常
            return getEncryptResult(new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode()));
        } else {
            //解密入参
            String encryptResult = DesEncryptUtil.aesDecrypt(encryptScript, propertyOperateMiniContentAesEncryptKey);
            if (StringUtils.isBlank(encryptResult)) {
                return getEncryptResult(new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode()));
            }
            encryptResult = encryptResult.replaceAll("&quot;","\"");
            //验签
            JSONObject jsStr = JSONObject.parseObject(encryptResult);//入参转json
            Map<String, Object> params = JsonUtil.toObject(encryptResult, HashMap.class);//入参转map
            String sign = jsStr.get("sign").toString();
            params.remove("sign");//移除签名
            if (!Md5EncryptUtil.checkCloudTalkSDKSign(params, sign, propertyOperateMd5EncryptKey)) {
                return getEncryptResult(new MessageVO(BaseErrorCodeEnum.CHECK_SIGN_ERR.getErrorCode()));
            }
            // 将参数放入请求域中
            HttpProtocolUtil.setRequestAttributes(params, request);

            Object result = thisJoinPoint.proceed();

            //签名且加密
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date();
            String createTime = df.format(date);
            String resultJson = JsonUtil.toJSON(result);
            JSONObject json = new JSONObject();
            Map<String, Object> jsonToMap = new HashMap<>();
            jsonToMap.put("data", resultJson);
            sign = Md5EncryptUtil.cloudDeviceMd5(jsonToMap, createTime, propertyOperateMd5EncryptKey);
            json.put("allData", resultJson);
            json.put("createTime", createTime);
            json.put("sign", sign);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("encryptScript", DesEncryptUtil.aesEncryptSDK(json.toJSONString(), propertyOperateMiniContentAesEncryptKey));

            return resultMap;
        }
    }

    /**
     * <desc>
     *      返回加密内容
     * </desc>
     *
     * @author chengshican
     * @createDate 2020/09/14
     */
    private Map<String, Object> getEncryptResult(Object result) throws Exception {
        String encryptResult = DesEncryptUtil.aesEncryptSDK(JsonUtil.toJSON(result), propertyOperateMiniContentAesEncryptKey);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("encryptScript", encryptResult);
        return resultMap;
    }
}
